package com.zjny.util;

import cn.hutool.core.util.NumberUtil;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * <p>
 * number 工具类
 * </p>
 *
 * @author cui haida
 * 2024/05/17/9:49
 */
public class NumberUtils extends NumberUtil {
    /**
     * x, y转成BigDecimal后相减
     * @param x x值（double类型）
     * @param y y值 （double类型）
     * @return result 处理结果
     */
    public static double subtract(double x, double y) {
        BigDecimal d1 = BigDecimal.valueOf(x);
        BigDecimal d2 = BigDecimal.valueOf(y);
        return d1.subtract(d2).doubleValue();
    }

    /**
     * x, y转成BigDecimal后相减，获得的结果再向上取整
     * @param x x值（double类型）
     * @param y y值 （double类型）
     * @return result 处理结果
     */
    public static double subtractUp(double x, double y) {
        double value = subtract(x, y);
        return roundUp(value);
    }

    /**
     * x, y转成BigDecimal后相减，获得的结果再向下取整
     * @param x x值（double类型）
     * @param y y值（double类型）
     * @return result 处理结果
     */
    public static double subtractDown(double x, double y) {
        double value = subtract(x, y);
        return roundDown(value);
    }

    /**
     * x, y转成BigDecimal后相减
     * @param x x值（double类型）
     * @param y y值 （double类型）
     * @return result 处理结果
     */
    public static double add(double x, double y) {
        BigDecimal d1 = BigDecimal.valueOf(x);
        BigDecimal d2 = BigDecimal.valueOf(y);
        return d1.add(d2).doubleValue();
    }

    /**
     * x, y转成BigDecimal后相乘
     * @param x x值（double类型）
     * @param y y值 （double类型）
     * @return result 处理结果
     */
    public static double multiply(double x, double y) {
        BigDecimal d1 = BigDecimal.valueOf(x);
        BigDecimal d2 = BigDecimal.valueOf(y);
        return d1.multiply(d2).doubleValue();
    }

    /**
     * x, y转成BigDecimal后相除
     * @param x x值（double类型）
     * @param y y值 （double类型）
     * @return result  处理结果
     */
    public static double divide(double x, double y, int scale) {
        BigDecimal d1 = BigDecimal.valueOf(x);
        BigDecimal d2 = BigDecimal.valueOf(y);
        return d1.divide(d2, scale).doubleValue();
    }

    /**
     * 向上取整
     * @param val val
     * @return result 处理结果
     */
    public static double roundUp(double val) {
        return roundUp(val, 0);
    }


    /**
     * 向上取整，可设置精度
     * @param val val
     * @param scale 精度
     * @return result 处理结果
     */
    public static double roundUp(double val, int scale) {
        BigDecimal dec = BigDecimal.valueOf(val);
        return dec.setScale(scale, RoundingMode.UP).doubleValue();
    }

    /**
     * 向下取整
     * @param val val
     * @return result 处理结果
     */
    public static double roundDown(double val) {
        return roundDown(val, 0);
    }

    /**
     * 向下取整，可设置精度
     * @param val val
     * @param scale 精度
     * @return result 处理结果
     */
    public static double roundDown(double val, int scale) {
        BigDecimal dec = BigDecimal.valueOf(val);
        return dec.setScale(scale, RoundingMode.DOWN).doubleValue();
    }

    /**
     * 四舍五入
     * @param val val 要进行四舍五入的数字
     * @return result 处理结果
     */
    public static double roundHalfUp(double val) {
        return roundHalfUp(val, 0);
    }

    /**
     * 四舍五入，可设置精度
     * @param val 要进行四舍五入的数字
     * @param scale 精度
     * @return 处理结果
     */
    public static double roundHalfUp(double val, int scale) {
        BigDecimal dec = BigDecimal.valueOf(val);
        return dec.setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 统计工具类 - 准确率
     *
     * @return 通过正确数，总数，数据源错误数拿到准确率
     */
    public static BigDecimal statistics(BigDecimal correctCount, BigDecimal totalCount, BigDecimal sourceErrorCount) {
        //准确率 = 正确数/（总量-数据源问题数）
        //总量 = 正确数 + 错误数 + 数据源问题 + 待定 + 新增
        if (correctCount.equals(new BigDecimal("0"))) {
            return new BigDecimal("0");
        }
        if (totalCount.equals(new BigDecimal("0"))) {
            return new BigDecimal("0");
        }
        return correctCount.divide(totalCount.subtract(sourceErrorCount), 4, RoundingMode.HALF_UP);
    }
}
